package org.jflame.commons.model;

import java.text.MessageFormat;

/**
 * 通用返回结果封装类.
 * <p>
 * 返回结果分为3个属性:状态码、结果描述、返回数据。默认结果码为成功200, 默认结果枚举请看:ResultEnum
 * 
 * @see ResultEnum
 * @author zyc
 */
public class CallResult<T> extends SimpleResult {

    private static final long serialVersionUID = 1L;

    private T data; // 返回数据

    /**
     * 构造函数,status默认成功
     */
    public CallResult() {
        this(ResultEnum.SUCCESS);
    }

    /**
     * 构造函数,使用默认结果枚举ResultEnum设置status和message
     * 
     * @param result ResultEnum
     */
    public CallResult(ResultEnum result) {
        setResult(result.getStatus(), result.getMessage());
    }

    public CallResult(int status) {
        setStatus(status);
    }

    public CallResult(int status, String message) {
        super(status, message);
    }

    /**
     * 构造函数
     * 
     * @param status
     * @param message
     * @param data
     */
    public CallResult(int status, String message, T data) {
        super(status, message);
        this.data = data;
    }

    public CallResult<T> status(int code) {
        setStatus(code);
        return this;
    }

    public CallResult<T> error(String message) {
        setResult(ResultEnum.SERVER_ERROR.getStatus(), message);
        return this;
    }

    public CallResult<T> failed(String message) {
        setResult(ResultEnum.FAILED.getStatus(), message);
        return this;
    }

    public CallResult<T> paramerror(String message) {
        setResult(ResultEnum.PARAM_ERROR.getStatus(), message);
        return this;
    }

    public CallResult<T> message(String message) {
        setMessage(message);
        return this;
    }

    /**
     * 设置结果数据,并设置状态为成功
     * 
     * @param data
     * @return 返回设置后的CallResult
     */
    public CallResult<T> success(T data) {
        setResult(ResultEnum.SUCCESS);
        this.data = data;
        return this;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public CallResult<T> result(BaseResult err) {
        setResult(err);
        return this;
    }

    /**
     * 结果是否成功,即等于ErrorEnum.SUCCESS.
     * 
     * @return boolean
     */
    public boolean success() {
        return getStatus() == ResultEnum.SUCCESS.getStatus();
    }

    public static <T> CallResult<T> ok() {
        return new CallResult<T>(ResultEnum.SUCCESS);
    }

    public static <T> CallResult<T> ok(T data) {
        return new CallResult<T>().success(data);
    }

    public static <T> CallResult<T> Error() {
        return new CallResult<T>(ResultEnum.SERVER_ERROR);
    }

    public static <T> CallResult<T> Error(String errMsg) {
        return new CallResult<T>(ResultEnum.SERVER_ERROR.getStatus(), errMsg);
    }

    public static <T> CallResult<T> Failed() {
        return new CallResult<T>(ResultEnum.FAILED);
    }

    public static <T> CallResult<T> Failed(String errMsg) {
        return new CallResult<T>(ResultEnum.FAILED.getStatus(), errMsg);
    }

    public static <T> CallResult<T> ParamError() {
        return new CallResult<T>(ResultEnum.PARAM_ERROR);
    }

    public static <T> CallResult<T> ParamError(String errMsg) {
        return new CallResult<T>(ResultEnum.PARAM_ERROR.getStatus(), errMsg);
    }

    @SuppressWarnings("unchecked")
    public static <T> CallResult<T> Result(BaseResult result) {
        if (result instanceof CallResult) {
            return (CallResult<T>) result;
        }
        return new CallResult<T>(result.getStatus(), result.getMessage());
    }

    @Override
    public String toString() {
        return MessageFormat.format("status={0},message={1},data={2}", getStatus(), getMessage(),
                (data == null ? "" : data.toString()));
    }
}
